import { BoxGeometry3D, Color, Float32BufferAttribute3D, MeshBasicMaterial3D, Node3D, PerspectiveCamera3D, Scene3D, WebGLRenderer3D } from 'feng3d-three';
import { PeppersGhostEffect3D } from '../../extension/effects/PeppersGhostEffect3D';

let container: HTMLDivElement;

let camera: PerspectiveCamera3D;
let scene: Scene3D;
let renderer: WebGLRenderer3D;
let effect: PeppersGhostEffect3D;
let group: Node3D;

init();
animate();

function init()
{
    container = document.createElement('div');
    document.body.appendChild(container);

    camera = new Node3D().addComponent('PerspectiveCamera3D', { fov: 60, aspect: window.innerWidth / window.innerHeight, near: 1, far: 100000 });

    scene = new Node3D().addComponent('Scene3D');

    group = new Node3D();
    scene.entity.addChild(group);

    // Cube

    const geometry = new BoxGeometry3D().toNonIndexed(); // ensure unique vertices for each triangle

    const position = geometry.attributes.position;
    const colors = [];
    const color = new Color();

    // generate for each side of the cube a different color

    for (let i = 0; i < position.count; i += 6)
    {
        color.setHex(Math.random() * 0xffffff);

        // first face

        colors.push(color.r, color.g, color.b);
        colors.push(color.r, color.g, color.b);
        colors.push(color.r, color.g, color.b);

        // second face

        colors.push(color.r, color.g, color.b);
        colors.push(color.r, color.g, color.b);
        colors.push(color.r, color.g, color.b);
    }

    geometry.setAttribute('color', new Float32BufferAttribute3D(colors, 3));

    const material = new MeshBasicMaterial3D({ vertexColors: true });

    for (let i = 0; i < 10; i++)
    {
        const cube = new Node3D().addComponent('Mesh3D', { geometry, material });
        cube.entity.position.x = Math.random() * 2 - 1;
        cube.entity.position.y = Math.random() * 2 - 1;
        cube.entity.position.z = Math.random() * 2 - 1;
        cube.entity.scale.multiplyScalar(Math.random() + 0.5);
        group.addChild(cube.entity);
    }

    renderer = scene.addComponent('WebGLRenderer3D');
    renderer.setPixelRatio(window.devicePixelRatio);
    container.appendChild(renderer.domElement);

    effect = new PeppersGhostEffect3D(renderer);
    effect.setSize(window.innerWidth, window.innerHeight);
    effect.cameraDistance = 5;

    window.addEventListener('resize', onWindowResize);
}

function onWindowResize()
{
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    effect.setSize(window.innerWidth, window.innerHeight);
}

function animate()
{
    requestAnimationFrame(animate);

    group.rotation.y += 0.01;

    effect.render(scene, camera);
}
